package com.jyt.motor.service.impl;

import com.jyt.motor.dao.*;
import com.jyt.motor.model.*;
import com.jyt.motor.service.ReceiveIWIRService;
import com.jyt.motor.util.CRC16;
import com.jyt.motor.util.SqlServer;
import com.jyt.motor.util.StringUtils;
import gnu.io.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ReceiveIWIRServiceImp extends ReceiveServiceImp implements ReceiveIWIRService{

    @Value("${motor.rxdCOMi}")
    private String rxdCOMi;
    @Value("${motor.rxdIP2}")
    private String rxdIP2;
    @Value("${motor.rxdPort2}")
    private String rxdPort2;

    private static volatile BlockingQueue<RawData> queue = new LinkedBlockingQueue<RawData>(60);
    private static Semaphore semaphore = new Semaphore(1);
    private static SerialPort serialPort;
    private Enumeration<CommPortIdentifier> portList;
    private boolean isTimeout = false;
    boolean isOpen = false;
    private OutputStream outputStream;
    private InputStream inputStream;
    private String addr;
    public static final int ALERT_CALSS_EXCEED=1;
    public static final int ALERT_CALSS_OFFLINE=3;
    private int offlineTimes=0;
    public static Map<Integer,Integer> motorOfflineTimes=new HashMap<>();
    private int exceptionTimes=0;
    public static Map<Integer,Integer> motorExceptionTimes=new HashMap<>();
    private int recoveryTimes=0;
    public static Map<Integer,Integer> motorRecoveryTimes=new HashMap<>();
    public static Integer converterTypeAW=1;
    //@Value("${get_data_cron}")
    public static Map<Integer,Integer> motorRecTimes=new HashMap<>();

    @Autowired
    MoMotorsMapper motorsMapper;

    @Autowired
    MoConverterMapper converterMapper;

    @Autowired
    MoDataRecMapper dataRecMapper;

    @Autowired
    MoAlertRecMapper alertRecMapper;

    @Autowired
    AlarmLampServiceImpSerialPort alarmLampServiceImpSerialPort;

    @Autowired
    SqlServer sqlServer;


    @Autowired
    SysConfigMapper sysConfigMapper;

    public int getSaveTimes() {
        try {
            return 60 / getGetDataCron();
        } catch (Exception e) {
            log.error(e.getMessage());
            return 1;
        }
    }
    public int getOfflineTimes()
    {
        if(offlineTimes==0)
        {
            offlineTimes=Integer.parseInt(sysConfigMapper.selectByConfKey("motor_offline_times").getConfValue().trim());
        }
        return offlineTimes;
    }

    public int getExceptionTimes()
    {
        if(exceptionTimes==0)
        {
            exceptionTimes=Integer.parseInt(sysConfigMapper.selectByConfKey("motor_exception_times").getConfValue().trim());
        }
        return exceptionTimes;
    }

    public int getRecoveryTimes()
    {
        if(recoveryTimes==0)
        {
            recoveryTimes=Integer.parseInt(sysConfigMapper.selectByConfKey("motor_recovery_times").getConfValue().trim());
        }
        return recoveryTimes;
    }
    public int getSaveDataCron()
    {
        if(saveDataCron==0)
        {
            saveDataCron=Integer.parseInt(sysConfigMapper.selectByConfKey("save_data_iwir_cron").getConfValue().trim());
        }
        return saveDataCron;
    }
    public String getMobiles()
    {
        if(StringUtils.isBlank(mobiles))
        {
            mobiles=sysConfigMapper.selectByConfKey("abnormal_SMS_mobiles").getConfValue().trim();
        }
        return mobiles;
    }
    public void clearMobiles()
    {
        mobiles="";
    }
    public void clearSaveDataCron()
    {
        saveDataCron=0;
    }
    public int getGetDataCron()
    {
        if(getDataCron==0)
        {
            getDataCron=Integer.parseInt(sysConfigMapper.selectByConfKey("get_data_iwir_cron").getConfValue().trim());
        }
        return getDataCron;
    }

    public void clearGetDataCron()
    {
        getDataCron=0;
    }
    private Socket socket = null;
    private int length = 0;
    private byte[] content = new byte[100];
    @Override
    public boolean getData() {
        if(StringUtils.isBlank(rxdIP2.trim())||StringUtils.isBlank(rxdPort2))
        {
            log.error("rxdIP2 or rxdPort2 is null!!!");
            return true;
        }
        List<MoConverter> converters = converterMapper.getInUseConverter(1);
        if (converters != null && converters.size() > 0) {
            try {
                socket = new Socket(rxdIP2.trim(), Integer.parseInt(rxdPort2.trim()));
                for (MoConverter converter : converters) {
                    byte[] data = socketData(converter.getCommand());
                    if(data==null)//模块离线
                    {
                        List<MotorMonitor> motorMonitors =motorsMapper.motorMoniSelect(converter.getCommand().substring(0,2),converterTypeAW);
                        List<MoAlertRec> moAlertRecs =new ArrayList<>();
                        List<Integer> offlineMotorIds= new ArrayList<>();
                        for(MotorMonitor motorMonitor : motorMonitors)
                        {
                            if(motorMonitor.getMoState()!=3&&motorMonitor.getMoState()!=0)
                            {
                                //连续异常 再报警
                                if(motorOfflineTimes.get(motorMonitor.getMoId())==null)
                                {
                                    motorOfflineTimes.put(motorMonitor.getMoId(),1);
                                }else if(motorOfflineTimes.get(motorMonitor.getMoId())<getOfflineTimes())
                                {
                                    motorOfflineTimes.put(motorMonitor.getMoId(),motorOfflineTimes.get(motorMonitor.getMoId())+1);
                                }else if(motorOfflineTimes.get(motorMonitor.getMoId())>=getOfflineTimes())
                                {
                                    if(isAlarmOffline!=0) {
                                        MoAlertRec alertRec = new MoAlertRec(ALERT_CALSS_OFFLINE, motorMonitor.getMoId(), motorMonitor.getMoName(), motorMonitor.getAreaId(),
                                                motorMonitor.getAreaName(), new Date(), BigDecimal.valueOf(0), motorMonitor.getUpperLimit(), motorMonitor.getLowerLimit(), 0,
                                                motorMonitor.getAreaName() + "->" + motorMonitor.getMoName() + "馬達離線，沒有數據！");
                                        moAlertRecs.add(alertRec);
                                    }
                                    offlineMotorIds.add(motorMonitor.getMoId());
                                    motorOfflineTimes.put(motorMonitor.getMoId(),0);
                                }
                            }
                        }
                        if (moAlertRecs.size() > 0) {
                            alertRecMapper.insertBatch(moAlertRecs);
                        }
                        if(offlineMotorIds.size()>0){
                            motorsMapper.updateStateByIds(0,"gray",offlineMotorIds);
                        }
                    }
                    else if (CRC16.checkCRC2(data)) {
                        addr = CRC16.bytesToString(new byte[]{data[0]}).trim();
                        int[] values = CRC16.byte2Info(Arrays.copyOfRange(data, 3, 19));
                        RawData rawData =new RawData(addr,values[0],values[1],values[2],values[3],values[4],values[5],values[6],values[7],new Date());
                        if(!queue.offer(rawData))
                        {
                            log.error("Data IWIR queue full!!!size:"+queue.size());
                            queue.poll();
                            queue.offer(rawData);
                        }
                        log.info("Receive IWIR data:addr="+rawData.getAddr()+",data1="+rawData.getData().get(0)+",data2="+rawData.getData().get(1)+",data3="+rawData.getData().get(2)+",data4="+rawData.getData().get(3)
                                +",data5="+rawData.getData().get(4)+",data6="+rawData.getData().get(5)+",data7="+rawData.getData().get(6)+",data8="+rawData.getData().get(7)+"------queue size:"+queue.size());
                    }
                }
                closeSocket();
            } catch (UnknownHostException e) {
                log.error("EBT串口服务器连接失败！！！"+e.getMessage());
                closeSocket();
                e.printStackTrace();
            } catch (IOException e) {
                log.error(e.getMessage());
                closeSocket();
                e.printStackTrace();
            }
        }
        return true;
    }
    private byte[] socketData(String comm)  {
        try {
            long time = new Date().getTime();
            //发送命令接收数据
            length = 0;
            //if (outputStream == null) {
            outputStream = socket.getOutputStream();
            // }
            outputStream.write(CRC16.command2Bytes(comm));
            outputStream.flush();
            socket.setKeepAlive(true);
            // if (inputStream == null) {
            inputStream = socket.getInputStream();
            // }
            while (inputStream.available() == 0) {
                Thread.sleep(100);
                if (new Date().getTime() >= time + receiveDataTimeout) {
                    log.error("Receiving IWIR data timeout.command:" + comm);
                    return null;
                }
            }
            if (inputStream.available() > 0) {
                while (length <= 0) {
                    length = inputStream.read(content);
                    if (new Date().getTime() >= time + receiveDataTimeout) {
                        log.error("Receiving IWIR data timeout.command:" + comm);
                        return null;
                    }
                }
            }
            byte[] data = Arrays.copyOfRange(content, 0, length);
            log.info("Receive IWIR data: " + CRC16.bytesToString(data));
            return data;
        } catch (InterruptedException e) {
            log.error(e.getMessage());
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            log.error(e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
    private void closeSocket() {
        try {
            if (inputStream != null) {
                inputStream.close();
                inputStream = null;
            }
            if (outputStream != null) {
                outputStream.close();
                outputStream = null;
            }
            if (socket != null) {
                socket.close();
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }
//    private void sendCommd(String commd) {
//        try {
//            isTimeout = !semaphore.tryAcquire(receiveDataTimeout, TimeUnit.MILLISECONDS);
//            if (isTimeout) {
//                log.error("Receiving IWIR data timeout.command:"+currentCommand);
//                //批量设备离线
//                if(currentCommand.length()>=2)
//                {
//                    List<MotorMonitor> motorMonitors =motorsMapper.motorMoniSelect(currentCommand.substring(0,2),converterTypeAW);
//                    List<MoAlertRec> moAlertRecs =new ArrayList<>();
//                    List<Integer> offlineMotorIds= new ArrayList<>();
//                    for(MotorMonitor motorMonitor : motorMonitors)
//                    {
//                        if(motorMonitor.getMoState()!=3&&motorMonitor.getMoState()!=0)
//                        {
//                            //连续异常 再报警
//                            if(motorOfflineTimes.get(motorMonitor.getMoId())==null)
//                            {
//                                motorOfflineTimes.put(motorMonitor.getMoId(),1);
//                            }else if(motorOfflineTimes.get(motorMonitor.getMoId())<getOfflineTimes())
//                            {
//                                motorOfflineTimes.put(motorMonitor.getMoId(),motorOfflineTimes.get(motorMonitor.getMoId())+1);
//                            }else if(motorOfflineTimes.get(motorMonitor.getMoId())>=getOfflineTimes())
//                            {
//                                if(isAlarmOffline!=0) {
//                                    MoAlertRec alertRec = new MoAlertRec(ALERT_CALSS_OFFLINE, motorMonitor.getMoId(), motorMonitor.getMoName(), motorMonitor.getAreaId(),
//                                            motorMonitor.getAreaName(), new Date(), BigDecimal.valueOf(0), motorMonitor.getUpperLimit(), motorMonitor.getLowerLimit(), 0,
//                                            motorMonitor.getAreaName() + "->" + motorMonitor.getMoName() + "马达离线，没有数据！");
//                                    moAlertRecs.add(alertRec);
//                                }
//                                offlineMotorIds.add(motorMonitor.getMoId());
//                                motorOfflineTimes.put(motorMonitor.getMoId(),0);
//                            }
//                        }
//                    }
//                    if (moAlertRecs.size() > 0) {
//                        alertRecMapper.insertBatch(moAlertRecs);
//                    }
//                    if(offlineMotorIds.size()>0){
//                        motorsMapper.updateStateByIds(0,"gray",offlineMotorIds);
//                    }
//                }
//            }
//            log.info("Receive IWIR data start......");
//            if (!isOpen) {
//                portList = CommPortIdentifier.getPortIdentifiers();
//                while (portList.hasMoreElements()) {
//                    CommPortIdentifier port = portList.nextElement();
//                    if (port.getPortType() == CommPortIdentifier.PORT_SERIAL&&rxdCOMi.equals(port.getName())) {
//
//                            serialPort = (SerialPort) port.open(Object.class.getSimpleName(), 2000);
//                            serialPort.addEventListener(this);
//                            serialPort.notifyOnDataAvailable(true);
//                            serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
//                                    SerialPort.PARITY_NONE);
//                            isOpen = true;
//                            // outputStream = new BufferedOutputStream(serialPort.getOutputStream());
//                            // outputStream = serialPort.getOutputStream();
//                            // outputStream.write(new byte[] { 0x01, 0x04, 0x00, 0x00, 0x00, 0x08, (byte)
//                            // 0xF0, (byte) 0x18 });
////						Thread.sleep(600);
//                            // closeSerialPort();
//                    }
//                }
//            }
//            if (isOpen) {
//                outputStream = serialPort.getOutputStream();
//                outputStream.write(CRC16.command2Bytes(commd));
//                currentCommand=commd;
//            }
//        } catch (IOException e) {
//            log.error(e.getMessage());
//            closeSerialPort();
//            isOpen = false;
//            e.printStackTrace();
//        } catch (TooManyListenersException e) {
//            log.error(e.getMessage());
//            closeSerialPort();
//            isOpen = false;
//            e.printStackTrace();
//        } catch (InterruptedException e) {
//            log.error(e.getMessage());
//            closeSerialPort();
//            isOpen = false;
//            e.printStackTrace();
//        } catch (PortInUseException e) {
//            log.error(e.getMessage());
//            closeSerialPort();
//            isOpen = false;
//            e.printStackTrace();
//        } catch (UnsupportedCommOperationException e) {
//            log.error(e.getMessage());
//            closeSerialPort();
//            isOpen = false;
//            e.printStackTrace();
//        }catch (Exception e){
//            log.error(e.getMessage());
//            closeSerialPort();
//            isOpen = false;
//            e.printStackTrace();
//        }
//    }
//    public void serialEvent(SerialPortEvent event) {
//        switch (event.getEventType()) {
//            case SerialPortEvent.BI:/* Break interrupt,通讯中断 */
//            case SerialPortEvent.OE:/* Overrun error，溢位错误 */
//            case SerialPortEvent.FE:/* Framing error，传帧错误 */
//            case SerialPortEvent.PE:/* Parity error，校验错误 */
//            case SerialPortEvent.CD:/* Carrier detect，载波检测 */
//            case SerialPortEvent.CTS:/* Clear to send，清除发送 */
//            case SerialPortEvent.DSR:/* Data set ready，数据设备就绪 */
//            case SerialPortEvent.RI:/* Ring indicator，响铃指示 */
//            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/* Output buffer is empty，输出缓冲区清空 */
//                break;
//            case SerialPortEvent.DATA_AVAILABLE:/* Data available at the serial port，端口有可用数据。读到缓冲数组，输出到终端 */
//                //模块类型不同，返回长度不同
//                byte[] readBuffer = new byte[21];
//                try {
//                    Thread.sleep(100);
//                    inputStream = serialPort.getInputStream();
//                    while (inputStream.read(readBuffer) != -1) {
//                        log.info("Receive IWIR data: " + CRC16.bytesToString(readBuffer));
//                        Date recTime = new Date();
//                        if (CRC16.checkCRC2(readBuffer)) {
//                            addr = CRC16.bytesToString(new byte[]{readBuffer[0]}).trim();
//                            int[] data = CRC16.byte2Info(Arrays.copyOfRange(readBuffer, 3, 19));
//                            RawData rawData =new RawData(addr,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],new Date());
//                            if(!queue.offer(rawData))
//                            {
//                                log.error("Data IWIR queue full!!!size:"+queue.size());
//                                queue.poll();
//                                queue.offer(rawData);
//                            }
//                            log.info("Receive IWIR data:addr="+rawData.getAddr()+",data1="+rawData.getData().get(0)+",data2="+rawData.getData().get(1)+",data3="+rawData.getData().get(2)+",data4="+rawData.getData().get(3)
//                                    +",data5="+rawData.getData().get(4)+",data6="+rawData.getData().get(5)+",data7="+rawData.getData().get(6)+",data8="+rawData.getData().get(7)+"------queue size:"+queue.size());
//                        }
//                        break;
//                    }
//                } catch (IOException e) {
//                    log.error(e.getMessage());
//                    closeSerialPort();
//                    isOpen = false;
//                    e.printStackTrace();
//                } catch (InterruptedException e) {
//                    log.error(e.getMessage());
//                    closeSerialPort();
//                    isOpen = false;
//                    e.printStackTrace();
//                }catch (Exception e) {
//                    log.error(e.getMessage());
//                    closeSerialPort();
//                    isOpen = false;
//                    e.printStackTrace();
//                }
//                finally {
//                    semaphore.release();
//                }
//                log.info("Receive IWIR data end......");
//        }
//    }
//
//    public void closeSerialPort() {
//        if (serialPort != null) {
//            serialPort.notifyOnDataAvailable(false);
//            serialPort.removeEventListener();
//            if (inputStream != null) {
//                try {
//                    inputStream.close();
//                    inputStream = null;
//                } catch (IOException e) {
//                    log.error(e.getMessage());
//                }
//            }
//            if (outputStream != null) {
//                try {
//                    outputStream.close();
//                    outputStream = null;
//                } catch (IOException e) {
//                    log.error(e.getMessage());
//                }
//            }
//            serialPort.close();
//            serialPort = null;
//        }
//    }

    /**
    *@Description:
    *@Param: 
    *@return: 
    *@Author: your name
    *@date: 2020/6/20
    */
    @Override
    public boolean saveData() {
        log.info("Save IWIR data start......");
        List<MoDataRec> moDataRecs =new ArrayList<>();
        List<MoAlertRec> moAlertRecs =new ArrayList<>();
        List<Integer> exceptionMotorIds=new ArrayList<>();
        List<Integer> exceptionMotorIdsRecovery=new ArrayList<>();
        List<Integer> offlineMotorIds= new ArrayList<>();
        List<Integer> offlineMotorIdsRecovery= new ArrayList<>();
        RawData data = queue.poll();
        while (data != null) {
            List<MotorMonitor> motorMonitors =motorsMapper.motorMoniSelect(data.getAddr(),converterTypeAW);
            MoDataRec rec;
            for(MotorMonitor motorMonitor : motorMonitors)
            {
                int k=data.getData().get(motorMonitor.getBitSn()-1);
                //3>0>2>1 3保养
                if (motorMonitor.getMoState() == 3) {
                    continue;
                }

                //0传感器离线
                if(k>=65525||k<=10)
                {
                       // List<MoAlertRec> alertRecs=alertRecMapper.selectUntreated(motorMonitor.getMoId());
                       // if(alertRecs.size()==0)
                    if(motorMonitor.getMoState()!=0)
                        {
                            //连续异常 再报警
                            if(motorOfflineTimes.get(motorMonitor.getMoId())==null)
                            {
                                motorOfflineTimes.put(motorMonitor.getMoId(),1);
                            }else if(motorOfflineTimes.get(motorMonitor.getMoId())<getOfflineTimes())
                            {
                                motorOfflineTimes.put(motorMonitor.getMoId(),motorOfflineTimes.get(motorMonitor.getMoId())+1);
                            }else if(motorOfflineTimes.get(motorMonitor.getMoId())>=getOfflineTimes())
                            {
                                if(isAlarmOffline!=0) {
                                    MoAlertRec alertRec = new MoAlertRec(ALERT_CALSS_OFFLINE, motorMonitor.getMoId(), motorMonitor.getMoName(), motorMonitor.getAreaId(),
                                            motorMonitor.getAreaName(), new Date(), BigDecimal.valueOf(0), motorMonitor.getUpperLimit(), motorMonitor.getLowerLimit(), 0,
                                            motorMonitor.getAreaName() + "->" + motorMonitor.getMoName() + "馬達離線，沒有數據！");
                                    moAlertRecs.add(alertRec);
                                }
                                offlineMotorIds.add(motorMonitor.getMoId());
                                motorOfflineTimes.put(motorMonitor.getMoId(),0);
                            }
                        }
                    continue;
                }else {
                    //离线恢复
                    motorOfflineTimes.put(motorMonitor.getMoId(),0);
                    if(motorMonitor.getMoState()==0)
                    {
                        offlineMotorIdsRecovery.add(motorMonitor.getMoId());
                        motorMonitor.setMoState(1);
                    }
                }

                //2、1 异常、正常
                rec=new MoDataRec(motorMonitor.getMoId(),motorMonitor.getMoName(),motorMonitor.getAreaId(),motorMonitor.getAreaName(),
                        motorMonitor.getMonitorId(),data.getRecTime(),motorMonitor.getUpperLimit(),motorMonitor.getLowerLimit(),motorMonitor.getMoState(),motorMonitor.getFixBase());
                float value=0;
                if (k > motorMonitor.getInputTo()) {
                    value = motorMonitor.getValueTo();
                } else if (k < motorMonitor.getInputFrom()) {
                    value = motorMonitor.getValueFrom();
                } else {
                    float avg = (motorMonitor.getInputTo() - motorMonitor.getInputFrom()) / (motorMonitor.getValueTo() - motorMonitor.getValueFrom());
                    value = ((float) k / avg - motorMonitor.getInputFrom() / avg);
                }
                rec.setOrigData(BigDecimal.valueOf(value));
                BigDecimal sdata = rec.getOrigData().add(rec.getFixBase());
                if (sdata.compareTo(BigDecimal.valueOf(motorMonitor.getValueFrom())) == -1 || sdata.compareTo(BigDecimal.valueOf(motorMonitor.getValueFrom())) == 0) {
                    rec.setRockData(BigDecimal.valueOf(motorMonitor.getValueFrom()));
                } else if (sdata.compareTo(BigDecimal.valueOf(motorMonitor.getValueTo())) == 1 || sdata.compareTo(BigDecimal.valueOf(motorMonitor.getValueTo())) == 0) {
                    rec.setRockData(BigDecimal.valueOf(motorMonitor.getValueTo()));
                } else {
                    rec.setRockData(sdata);
                }
                log.info("Save IWIR data:moid="+rec.getMoId()+",moName="+rec.getMoName()+",rockData="+rec.getRockData()+",limit="+rec.getLowerLimit()+"~~"+rec.getUpperLimit());
                //洪总命令一分钟内保留一条数据，减少数据库数据
                if(motorRecTimes.get(rec.getMoId())==null){
                    motorRecTimes.put(rec.getMoId(),1);
                }else{
                    motorRecTimes.put(rec.getMoId(),motorRecTimes.get(rec.getMoId())+1);
                }
                if(motorRecTimes.get(rec.getMoId())>=getSaveTimes()) {
                    moDataRecs.add(rec);
                    motorRecTimes.put(rec.getMoId(),0);
                }
                //判断报警
                if(motorMonitor.getMoState()==1&&(motorMonitor.getLowerLimit().compareTo(BigDecimal.valueOf(-1))!=0||motorMonitor.getUpperLimit().compareTo(BigDecimal.valueOf(-1))!=0)){
                    if(motorMonitor.getUpperLimit().compareTo(BigDecimal.valueOf(-1))!=0&&rec.getRockData().compareTo(motorMonitor.getUpperLimit())==1)
                    {
                        //连续异常 再报警
                        if(motorExceptionTimes.get(motorMonitor.getMoId())==null)
                        {
                            motorExceptionTimes.put(motorMonitor.getMoId(),1);
                        }else if(motorExceptionTimes.get(motorMonitor.getMoId())<getExceptionTimes())
                        {
                            motorExceptionTimes.put(motorMonitor.getMoId(),motorExceptionTimes.get(motorMonitor.getMoId())+1);
                        }else if(motorExceptionTimes.get(motorMonitor.getMoId())>=getExceptionTimes())
                        {
                            MoAlertRec alertRec =new MoAlertRec(ALERT_CALSS_EXCEED,motorMonitor.getMoId(),motorMonitor.getMoName(),motorMonitor.getAreaId(),
                                    motorMonitor.getAreaName(),new Date(),rec.getRockData(),motorMonitor.getUpperLimit(),motorMonitor.getLowerLimit(),0,
                                    motorMonitor.getAreaName()+"->"+motorMonitor.getMoName()+"馬達故障、螺絲鬆動！");
                            moAlertRecs.add(alertRec);
                            exceptionMotorIds.add(motorMonitor.getMoId());
                            motorExceptionTimes.put(motorMonitor.getMoId(),0);
                            sqlServer.addNotes(getMobiles(),motorMonitor.getAreaName()+"->"+motorMonitor.getMoName()+"馬達故障、螺絲鬆動！");
                        }

                    }else if(motorMonitor.getLowerLimit().compareTo(BigDecimal.valueOf(-1))!=0&&rec.getRockData().compareTo(motorMonitor.getLowerLimit())==-1)
                    {
                        //连续异常 再报警
                        if(motorExceptionTimes.get(motorMonitor.getMoId())==null)
                        {
                            motorExceptionTimes.put(motorMonitor.getMoId(),1);
                        }else if(motorExceptionTimes.get(motorMonitor.getMoId())<getExceptionTimes())
                        {
                            motorExceptionTimes.put(motorMonitor.getMoId(),motorExceptionTimes.get(motorMonitor.getMoId())+1);
                        }else if(motorExceptionTimes.get(motorMonitor.getMoId())>=getExceptionTimes())
                        {
                            MoAlertRec alertRec =new MoAlertRec(ALERT_CALSS_EXCEED,motorMonitor.getMoId(),motorMonitor.getMoName(),motorMonitor.getAreaId(),
                                    motorMonitor.getAreaName(),new Date(),rec.getRockData(),motorMonitor.getUpperLimit(),motorMonitor.getLowerLimit(),0,
                                    motorMonitor.getAreaName()+"->"+motorMonitor.getMoName()+"馬達停機！");
                            moAlertRecs.add(alertRec);
                            exceptionMotorIds.add(motorMonitor.getMoId());
                            motorExceptionTimes.put(motorMonitor.getMoId(),0);
                            sqlServer.addNotes(getMobiles(),motorMonitor.getAreaName()+"->"+motorMonitor.getMoName()+"馬達停機！");
                        }
                    }
                }else if(motorMonitor.getMoState()==2){
                    //报警恢复
                    boolean isOk=false;
                    if(motorMonitor.getLowerLimit().compareTo(BigDecimal.valueOf(-1))==0&&motorMonitor.getUpperLimit().compareTo(BigDecimal.valueOf(-1))==0)
                    {
                        isOk=true;
                    }else if(motorMonitor.getLowerLimit().compareTo(BigDecimal.valueOf(-1))==0&&motorMonitor.getUpperLimit().compareTo(BigDecimal.valueOf(-1))!=0)
                    {
                        if(rec.getRockData().compareTo(motorMonitor.getUpperLimit())==-1||rec.getRockData().compareTo(motorMonitor.getUpperLimit())==0)
                        {
                           isOk=true;
                        }
                    }else if(motorMonitor.getLowerLimit().compareTo(BigDecimal.valueOf(-1))!=0&&motorMonitor.getUpperLimit().compareTo(BigDecimal.valueOf(-1))==0)
                    {
                        if(rec.getRockData().compareTo(motorMonitor.getLowerLimit())==1||rec.getRockData().compareTo(motorMonitor.getLowerLimit())==0)
                        {
                            isOk=true;
                        }
                    }else {
                        if((rec.getRockData().compareTo(motorMonitor.getLowerLimit())==1||rec.getRockData().compareTo(motorMonitor.getLowerLimit())==0)&&(rec.getRockData().compareTo(motorMonitor.getUpperLimit())==-1||rec.getRockData().compareTo(motorMonitor.getUpperLimit())==0))
                        {
                            isOk=true;
                        }
                    }
                    if(isOk)
                    {
                        //连续恢复 再恢复
                        if(motorRecoveryTimes.get(motorMonitor.getMoId())==null)
                        {
                            motorRecoveryTimes.put(motorMonitor.getMoId(),1);
                        }else if(motorRecoveryTimes.get(motorMonitor.getMoId())<getRecoveryTimes())
                        {
                            motorRecoveryTimes.put(motorMonitor.getMoId(),motorRecoveryTimes.get(motorMonitor.getMoId())+1);
                        }else if(motorRecoveryTimes.get(motorMonitor.getMoId())>=getRecoveryTimes())
                        {
                            exceptionMotorIdsRecovery.add(motorMonitor.getMoId());
                            motorRecoveryTimes.put(motorMonitor.getMoId(),0);
                        }
                    }
                }
            }
            data = queue.poll();
        }
        if (moDataRecs.size() > 0) {
            //batch insert
            dataRecMapper.insertBatch(moDataRecs);
        }
        if (moAlertRecs.size() > 0) {
            //状态覆盖，低等级异常自动关闭
            alertRecMapper.updateRecoveryByRecs(new Date(),"状态覆盖,产生新异常。",moAlertRecs);
            alertRecMapper.insertBatch(moAlertRecs);
        }
        if(offlineMotorIds.size()>0){
            motorsMapper.updateStateByIds(0,"gray",offlineMotorIds);
        }
        if(offlineMotorIdsRecovery.size()>0)
        {
            if(isAlarmOffline!=0) {
                alertRecMapper.updateRecoveryByIds(new Date(),"离线设备恢复正常！",3,offlineMotorIdsRecovery);
            }
            motorsMapper.updateStateByIds(1, "green", offlineMotorIdsRecovery);
        }
        if(exceptionMotorIds.size()>0)
        {
            motorsMapper.updateStateByIds(2,"red",exceptionMotorIds);
        }
        if(exceptionMotorIdsRecovery.size()>0)
        {
            motorsMapper.updateStateByIds(1,"green",exceptionMotorIdsRecovery);
            alertRecMapper.updateRecoveryByIds(new Date(),"马达振幅恢复正常！",1,exceptionMotorIdsRecovery);
        }

        log.info("Save IWIR data end......");
        //更新报警灯状态
        if(motorsMapper.countAlarmMotor()>0)
        {
            alarmLampServiceImpSerialPort.openAlarmLamp();
        }else {
            alarmLampServiceImpSerialPort.closeAlarmLamp();
        }


        return true;
    }

    public void clearConf(){
        offlineTimes=0;
        exceptionTimes=0;
        recoveryTimes=0;
    }
}
